package cn.edu.nwpu.warehousemanagement.interceptors;

import cn.edu.nwpu.warehousemanagement.util.JwtUtil;
import cn.edu.nwpu.warehousemanagement.util.LogUtil;
import cn.edu.nwpu.warehousemanagement.util.RedisUtil;
import cn.edu.nwpu.warehousemanagement.util.ThreadLocalUtil;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.Map;

/**
 * @author Loadstar
 * @version 1.0
 */
@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Resource
    private RedisUtil redisUtil;

    /**
     * 登录校验,检查token是否有效
     *
     * @param request  请求
     * @param response 响应
     * @param handler  处理器
     * @return 是否放行
     */
    @Override
    public boolean preHandle(HttpServletRequest request,
                             @Nonnull HttpServletResponse response,
                             @Nonnull Object handler) {
        //从请求的header的Authorization中获取token
        String token = request.getHeader("Authorization");
        try {

            if (null == redisUtil.getJWT(token)) {
                throw new RuntimeException("登录信息已失效");
            }
            //验证token，若失败则报错
            Map<String, Object> claims = JwtUtil.parseToken(token);
            //把业务数据存储到ThreadLocal中
            ThreadLocalUtil.set(claims);
            //通过则返回true，即放行
            return true;
        } catch (Exception e) {
            //验证失败，设置http响应码为401
            response.setStatus(401);
            LogUtil.debug(LoginInterceptor.class, "登录校验失败", e);
            //不放行
            return false;
        }

    }

    @Override
    public void afterCompletion(@Nonnull HttpServletRequest request,
                                @Nonnull HttpServletResponse response,
                                @Nonnull Object handler,
                                Exception ex) throws Exception {
        ThreadLocalUtil.remove();
    }
}
